<!DOCTYPE html>

<html>
<head>
  <title>optparse.coffee</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  <link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
  <div id="container">
    <div id="background"></div>
    
      <ul id="jump_to">
        <li>
          <a class="large" href="javascript:void(0);">Jump To &hellip;</a>
          <a class="small" href="javascript:void(0);">+</a>
          <div id="jump_wrapper">
          <div id="jump_page_wrapper">
            <div id="jump_page">
              
                
                <a class="source" href="browser.html">
                  browser.coffee
                </a>
              
                
                <a class="source" href="cake.html">
                  cake.coffee
                </a>
              
                
                <a class="source" href="coffeescript.html">
                  coffeescript.coffee
                </a>
              
                
                <a class="source" href="command.html">
                  command.coffee
                </a>
              
                
                <a class="source" href="grammar.html">
                  grammar.coffee
                </a>
              
                
                <a class="source" href="helpers.html">
                  helpers.coffee
                </a>
              
                
                <a class="source" href="index.html">
                  index.coffee
                </a>
              
                
                <a class="source" href="lexer.html">
                  lexer.coffee
                </a>
              
                
                <a class="source" href="nodes.html">
                  nodes.coffee
                </a>
              
                
                <a class="source" href="optparse.html">
                  optparse.coffee
                </a>
              
                
                <a class="source" href="register.html">
                  register.coffee
                </a>
              
                
                <a class="source" href="repl.html">
                  repl.coffee
                </a>
              
                
                <a class="source" href="rewriter.html">
                  rewriter.coffee
                </a>
              
                
                <a class="source" href="scope.html">
                  scope.litcoffee
                </a>
              
                
                <a class="source" href="sourcemap.html">
                  sourcemap.litcoffee
                </a>
              
            </div>
          </div>
        </li>
      </ul>
    
    <ul class="sections">
        
          <li id="title">
              <div class="annotation">
                  <h1>optparse.coffee</h1>
              </div>
          </li>
        
        
        
        <li id="section-1">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-1">&#x00a7;</a>
              </div>
              
            </div>
            
            <div class="content"><div class='highlight'><pre>{repeat} = <span class="hljs-built_in">require</span> <span class="hljs-string">&#x27;./helpers&#x27;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-2">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-2">&#x00a7;</a>
              </div>
              <p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
Use it like so:</p>
<pre><code>parser  = <span class="hljs-keyword">new</span> OptionParser switches, helpBanner
options = parser.parse process.argv
</code></pre>
<p>The first non-option is considered to be the start of the file (and file
option) list, and all subsequent arguments are left unparsed.</p>
<p>The <code>coffee</code> command uses an instance of <strong>OptionParser</strong> to parse its
command-line arguments in <code>src/command.coffee</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.OptionParser = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OptionParser</span></span></pre></div></div>
            
        </li>
        
        
        <li id="section-3">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-3">&#x00a7;</a>
              </div>
              <p>Initialize with a list of valid options, in the form:</p>
<pre><code>[short-flag, long-flag, description]
</code></pre>
<p>Along with an optional banner for the usage help.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  constructor: <span class="hljs-function"><span class="hljs-params">(ruleDeclarations, @banner)</span> -&gt;</span>
    @rules = buildRules ruleDeclarations</pre></div></div>
            
        </li>
        
        
        <li id="section-4">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-4">&#x00a7;</a>
              </div>
              <p>Parse the list of arguments, populating an <code>options</code> object with all of the
specified options, and return it. Options after the first non-option
argument are treated as arguments. <code>options.arguments</code> will be an array
containing the remaining arguments. This is a simpler API than many option
parsers that allow you to attach callback actions for every flag. Instead,
you’re responsible for interpreting the options object.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  parse: <span class="hljs-function"><span class="hljs-params">(args)</span> -&gt;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-5">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-5">&#x00a7;</a>
              </div>
              <p>The CoffeeScript option parser is a little odd; options after the first
non-option argument are treated as non-option arguments themselves.
Optional arguments are normalized by expanding merged flags into multiple
flags. This allows you to have <code>-wl</code> be the same as <code>--watch --lint</code>.
Note that executable scripts with a shebang (<code>#!</code>) line should use the
line <code>#!/usr/bin/env coffee</code>, or <code>#!/absolute/path/to/coffee</code>, without a
<code>--</code> argument after, because that will fail on Linux (see #3946).</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    {rules, positional} = normalizeArguments args, @rules.flagDict
    options = {}</pre></div></div>
            
        </li>
        
        
        <li id="section-6">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-6">&#x00a7;</a>
              </div>
              <p>The <code>argument</code> field is added to the rule instance non-destructively by
<code>normalizeArguments</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">for</span> {hasArgument, argument, isList, name} <span class="hljs-keyword">in</span> rules
      <span class="hljs-keyword">if</span> hasArgument
        <span class="hljs-keyword">if</span> isList
          options[name] ?= []
          options[name].push argument
        <span class="hljs-keyword">else</span>
          options[name] = argument
      <span class="hljs-keyword">else</span>
        options[name] = <span class="hljs-literal">true</span>

    <span class="hljs-keyword">if</span> positional[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">&#x27;--&#x27;</span>
      options.doubleDashed = <span class="hljs-literal">yes</span>
      positional = positional[<span class="hljs-number">1.</span>.]

    options.arguments = positional
    options</pre></div></div>
            
        </li>
        
        
        <li id="section-7">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-7">&#x00a7;</a>
              </div>
              <p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
of the valid options, for <code>--help</code> and such.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>  help: <span class="hljs-function">-&gt;</span>
    lines = []
    lines.unshift <span class="hljs-string">&quot;<span class="hljs-subst">#{@banner}</span>\n&quot;</span> <span class="hljs-keyword">if</span> @banner
    <span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> @rules.ruleList
      spaces  = <span class="hljs-number">15</span> - rule.longFlag.length
      spaces  = <span class="hljs-keyword">if</span> spaces &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> repeat <span class="hljs-string">&#x27; &#x27;</span>, spaces <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;&#x27;</span>
      letPart = <span class="hljs-keyword">if</span> rule.shortFlag <span class="hljs-keyword">then</span> rule.shortFlag + <span class="hljs-string">&#x27;, &#x27;</span> <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;    &#x27;</span>
      lines.push <span class="hljs-string">&#x27;  &#x27;</span> + letPart + rule.longFlag + spaces + rule.description
    <span class="hljs-string">&quot;\n<span class="hljs-subst">#{ lines.join(<span class="hljs-string">&#x27;\n&#x27;</span>) }</span>\n&quot;</span></pre></div></div>
            
        </li>
        
        
        <li id="section-8">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-8">&#x00a7;</a>
              </div>
              <h2 id="helpers">Helpers</h2>

            </div>
            
        </li>
        
        
        <li id="section-9">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-9">&#x00a7;</a>
              </div>
              
            </div>
            
        </li>
        
        
        <li id="section-10">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-10">&#x00a7;</a>
              </div>
              <p>Regex matchers for option flags on the command line and their rules.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>LONG_FLAG  = <span class="hljs-regexp">/^(--\w[\w\-]*)/</span>
SHORT_FLAG = <span class="hljs-regexp">/^(-\w)$/</span>
MULTI_FLAG = <span class="hljs-regexp">/^-(\w{2,})/</span></pre></div></div>
            
        </li>
        
        
        <li id="section-11">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-11">&#x00a7;</a>
              </div>
              <p>Matches the long flag part of a rule for an option with an argument. Not
applied to anything in process.argv.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>OPTIONAL   = <span class="hljs-regexp">/\[(\w+(\*?))\]/</span></pre></div></div>
            
        </li>
        
        
        <li id="section-12">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-12">&#x00a7;</a>
              </div>
              <p>Build and return the list of option rules. If the optional <em>short-flag</em> is
unspecified, leave it out by padding with <code>null</code>.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRules</span> = <span class="hljs-params">(ruleDeclarations)</span> -&gt;</span>
  ruleList = <span class="hljs-keyword">for</span> tuple <span class="hljs-keyword">in</span> ruleDeclarations
    tuple.unshift <span class="hljs-literal">null</span> <span class="hljs-keyword">if</span> tuple.length &lt; <span class="hljs-number">3</span>
    buildRule tuple...
  flagDict = {}
  <span class="hljs-keyword">for</span> rule <span class="hljs-keyword">in</span> ruleList</pre></div></div>
            
        </li>
        
        
        <li id="section-13">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-13">&#x00a7;</a>
              </div>
              <p><code>shortFlag</code> is null if not provided in the rule.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">for</span> flag <span class="hljs-keyword">in</span> [rule.shortFlag, rule.longFlag] <span class="hljs-keyword">when</span> flag?
      <span class="hljs-keyword">if</span> flagDict[flag]?
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">&quot;flag <span class="hljs-subst">#{flag}</span> for switch <span class="hljs-subst">#{rule.name}</span>
          was already declared for switch <span class="hljs-subst">#{flagDict[flag].name}</span>&quot;</span>
      flagDict[flag] = rule

  {ruleList, flagDict}</pre></div></div>
            
        </li>
        
        
        <li id="section-14">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-14">&#x00a7;</a>
              </div>
              <p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
description of what the option does.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">buildRule</span> = <span class="hljs-params">(shortFlag, longFlag, description)</span> -&gt;</span>
  match     = longFlag.match(OPTIONAL)
  shortFlag = shortFlag?.match(SHORT_FLAG)[<span class="hljs-number">1</span>]
  longFlag  = longFlag.match(LONG_FLAG)[<span class="hljs-number">1</span>]
  {
    name:         longFlag.replace <span class="hljs-regexp">/^--/</span>, <span class="hljs-string">&#x27;&#x27;</span>
    shortFlag:    shortFlag
    longFlag:     longFlag
    description:  description
    hasArgument:  !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">1</span>])
    isList:       !!(match <span class="hljs-keyword">and</span> match[<span class="hljs-number">2</span>])
  }
<span class="hljs-function">
<span class="hljs-title">normalizeArguments</span> = <span class="hljs-params">(args, flagDict)</span> -&gt;</span>
  rules = []
  positional = []
  needsArgOpt = <span class="hljs-literal">null</span>
  <span class="hljs-keyword">for</span> arg, argIndex <span class="hljs-keyword">in</span> args</pre></div></div>
            
        </li>
        
        
        <li id="section-15">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-15">&#x00a7;</a>
              </div>
              <p>If the previous argument given to the script was an option that uses the
next command-line argument as its argument, create copy of the option’s
rule with an <code>argument</code> field.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>    <span class="hljs-keyword">if</span> needsArgOpt?
      withArg = <span class="hljs-built_in">Object</span>.assign {}, needsArgOpt.rule, {argument: arg}
      rules.push withArg
      needsArgOpt = <span class="hljs-literal">null</span>
      <span class="hljs-keyword">continue</span>

    multiFlags = arg.match(MULTI_FLAG)?[<span class="hljs-number">1</span>]
      .split(<span class="hljs-string">&#x27;&#x27;</span>)
      .map (flagName) -&gt; <span class="hljs-string">&quot;-<span class="hljs-subst">#{flagName}</span>&quot;</span>
    <span class="hljs-keyword">if</span> multiFlags?
      multiOpts = multiFlags.map (flag) -&gt;
        rule = flagDict[flag]
        <span class="hljs-keyword">unless</span> rule?
          <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">&quot;unrecognized option <span class="hljs-subst">#{flag}</span> in multi-flag <span class="hljs-subst">#{arg}</span>&quot;</span>
        {rule, flag}</pre></div></div>
            
        </li>
        
        
        <li id="section-16">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-16">&#x00a7;</a>
              </div>
              <p>Only the last flag in a multi-flag may have an argument.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      [innerOpts..., lastOpt] = multiOpts
      <span class="hljs-keyword">for</span> {rule, flag} <span class="hljs-keyword">in</span> innerOpts
        <span class="hljs-keyword">if</span> rule.hasArgument
          <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">&quot;cannot use option <span class="hljs-subst">#{flag}</span> in multi-flag <span class="hljs-subst">#{arg}</span> except
          as the last option, because it needs an argument&quot;</span>
        rules.push rule
      <span class="hljs-keyword">if</span> lastOpt.rule.hasArgument
        needsArgOpt = lastOpt
      <span class="hljs-keyword">else</span>
        rules.push lastOpt.rule
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> ([LONG_FLAG, SHORT_FLAG].some (pat) -&gt; arg.match(pat)?)
      singleRule = flagDict[arg]
      <span class="hljs-keyword">unless</span> singleRule?
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">&quot;unrecognized option <span class="hljs-subst">#{arg}</span>&quot;</span>
      <span class="hljs-keyword">if</span> singleRule.hasArgument
        needsArgOpt = {rule: singleRule, flag: arg}
      <span class="hljs-keyword">else</span>
        rules.push singleRule
    <span class="hljs-keyword">else</span></pre></div></div>
            
        </li>
        
        
        <li id="section-17">
            <div class="annotation">
              
              <div class="sswrap ">
                <a class="ss" href="#section-17">&#x00a7;</a>
              </div>
              <p>This is a positional argument.</p>

            </div>
            
            <div class="content"><div class='highlight'><pre>      positional = args[argIndex..]
      <span class="hljs-keyword">break</span>

  <span class="hljs-keyword">if</span> needsArgOpt?
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span> <span class="hljs-string">&quot;value required for <span class="hljs-subst">#{needsArgOpt.flag}</span>, but it was the last
    argument provided&quot;</span>
  {rules, positional}</pre></div></div>
            
        </li>
        
    </ul>
  </div>
</body>
</html>
